#ifndef SELF_DEFINE_FUNCTIONS_H_INCLUDED
#define SELF_DEFINE_FUNCTIONS_H_INCLUDED


#include "./CEC2013/Header.h"
#include <math.h>
#include <boost/random.hpp>
#include <boost/random/uniform_int.hpp>
#include <boost/random/cauchy_distribution.hpp>
#include <boost/random/normal_distribution.hpp>
#include <boost/random/uniform_real.hpp>
#include <map>
#include <string>



const int Population_Size = 30;

const int Dim = 1000;

const double Top_Ratio = 0.2;

const int Elite_Number = (int)(Top_Ratio*Population_Size);



struct NewType
{
    double data;
    int id;
};

Benchmarks* generateFuncObj(int funcID);

bool Compare_NewType( NewType data1, NewType data2 );

double Distance( double *individual1, double *individual2, int dim );

void Update_Pool_Nearest( double *insert_gbest, double result, double **pool, double *pool_results, int pool_size, int dim );

void Update_Pool_Random( double *insert_gbest, double result, double **pool, double *pool_results, int pool_size, int dim );

void Update_Pool_Random_K_Nearest( double *insert_gbest, double result, double **pool, double *pool_results, int pool_size, int dim, int K );

void Get_Elites( int *elites, int *non_elites, int elite_num, int non_elite_num, double *population_results, int population_size );

void Elite_Mean( double *elite_mean, int *elites, double **population, int elite_num, int dim );

void Population_Mean( double *population_mean, double **population, int population_size, int dim );

void Individual_Update( double *position, double *speed, double *exemplar1, double *exemplar2, double *Lower_Bound, double *Upper_Bound, int dim, double phi );

int Intersection( int *last_elites, int *current_elites, int elite_num );

void Selected_Candidates_Random( double *buffer, int candidate_num, double **population, double *population_results, int population_size, int dim );

void Selected_Candidates_Random_Index( int *candiate_index, int candidate_num, int population_size );

void Compute_Probability( double *probability, double *population_result, int population_size );

int Roulette_Wheel_Selection( double *probability, double random_probability, int probability_size );

void Selected_Candidates_Roulette( double *buffer, int candidate_num, double **population, double *population_results, int population_size, int dim );

void Selected_Candidates_Roulette_Index( int *candidate_index, int candidate_num,  double *population_results, int population_size );

void Compute_Elite_Probability( double *probability, int *elites, double *population_results, int elite_num );

void Compute_Elite_Candidate_Probability( double *probability, int *elite, double *population_results, int *candidate, double *pool_results, int elite_num, int candidate_num );

void Compute_Elite_Candidate_Probability_Parallel( double *probability, int *elite, double *population_results, double *buffer, int elite_num,  int candidate_num, int dim );




#endif // SELF_DEFINE_FUNCTIONS_H_INCLUDED
